﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Galaktika.BI.Silverlight.ClientApp.Web.Runtime;
using Galaktika.BI.Extensibility.Dom.Dac;
using Galaktika.BI.Silverlight.ClientApp.Web.Runtime.Services;
using Ranet.Olap.Core.Metadata;
using Ranet.AgOlap.Controls.General.ClientServer;
using Galaktika.BI.Silverlight.Services;
//using Ranet.Olap.Core.Compressor;
using System.Configuration;
using Microsoft.AnalysisServices.AdomdClient;
using Ranet.Olap.Core.Providers;
using Ranet.Olap.Core;

namespace Galaktika.BI.Silverlight.ClientApp.Web.Commands
{
    public class GetMetadataCommand : ServerCommand
    {
        bool UseCompress = true;
        public GetMetadataCommand(InvokeSchema invoker)
            : base(Galaktika.BI.Silverlight.Commands.CommandId.GetMetadataCommandId)
        {
            if (ConfigurationSettings.AppSettings.AllKeys.Contains("CompressData"))
            {
                String str = ConfigurationSettings.AppSettings["CompressData"];
                try
                {
                    if (!String.IsNullOrEmpty(str))
                        UseCompress = Convert.ToBoolean(str);
                }
                catch (System.FormatException)
                {
                }
            }
            this.Args = XmlUtility.XmlStr2Obj<MetadataQuery>(invoker[KnownInvokeArgs.MetadataQueryInfo]);
            this.ConnectionString = invoker[KnownInvokeArgs.ConnectionString];
        }

        public MetadataQuery Args { get; private set; }
        public String ConnectionString { get; private set; }

        OlapMetadataProviderEx m_Provider = null;
        private OlapMetadataProviderEx DataProvider
        {
            get
            {
                if (m_Provider == null)
                {
                    m_Provider = new OlapMetadataProviderEx(new ConnectionInfo(this.Args.Connection, ConnectionString));
                }
                return m_Provider;
            }
        }

        public override InvokeResultSchema Invoke()
        {
            InvokeResultSchema result = new InvokeResultSchema(base.Id);
            result.ContentType = KnownContentTypes.Empty;
            try
            {
                MetadataQuery args = this.Args;

                if (DataProvider != null)
                {
                    String res = String.Empty;
                    switch(args.QueryType)
                    {    
                        case MetadataQueryType.GetMeasures:
                            res = GetMeasures(args);
                            break;
                        case MetadataQueryType.GetMeasure:
                            res = GetMeasure(args);
                            break;
                        case MetadataQueryType.GetKPIs:
                            res = GetKPIs(args);
                            break;
                        case MetadataQueryType.GetKPI:
                            res = GetKPI(args);
                            break;
                        case MetadataQueryType.GetLevels:
                            res = GetLevels(args);
                            break;
                        case MetadataQueryType.GetLevel:
                            res = GetLevel(args);
                            break;
                        case MetadataQueryType.GetDimensions:
                            res = GetDimensions(args);
                            break;
                        case MetadataQueryType.GetHierarchies:
                            res = GetHierarchies(args);
                            break;
                        case MetadataQueryType.GetDimension:
                            res = GetDimension(args);
                            break;
                        case MetadataQueryType.GetHierarchy:
                            res = GetHierarchy(args);
                            break;
                        case MetadataQueryType.GetLevelProperties:
                            res = GetLevelProperties(args);
                            break;
                        case MetadataQueryType.GetCubeMetadata:
                        case MetadataQueryType.GetCubeMetadata_AllMembers:
                            res = GetCubeMetadata(args);
                            break;
                    }
                    
                    result.Content = res;
                    //if (UseCompress)
                    //{
                    //    // Архивация строки
                    //    String compesed = ZipCompressor.CompressToBase64String(res);
                    //    result.Content = compesed;
                    //    result.IsArchive = true;
                    //}
                    result.ContentType = KnownContentTypes.MultidimData;
                }

                return result;
            }
            catch (AdomdConnectionException connection_ex)
            {
                result.ContentType = KnownContentTypes.ADOMDError;
                result.Content = connection_ex.Message;
            }
            catch (AdomdErrorResponseException response_ex)
            {
                result.ContentType = KnownContentTypes.ADOMDError;
                result.Content = response_ex.Message;
            }
            catch (OlapMetadataResponseException metadata_ex)
            {
                result.Content = metadata_ex.Message;
                result.ContentType = KnownContentTypes.ADOMDError;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        String GetCubeMetadata(MetadataQuery args)
        {
            CubeDefInfo info = DataProvider.GetCubeMetadata(args.CubeName, args.QueryType);
            return XmlUtility.Obj2XmlStr(info, Common.Namespace);
        }

        String GetLevelProperties(MetadataQuery args)
        {
            // Делать коллекцию с ключем "Имя свойства" нельзя, т.к. свойства KEY1, KEY2 и т.д. есть не у всех уровней и например в контроле выбора элемента измерения при построении уловия поиска придется проверять для каких уровней они есть, а для каких нету
            List<LevelPropertyInfo> list = new List<LevelPropertyInfo>();
            if (String.IsNullOrEmpty(args.LevelUniqueName))
            {
                Dictionary<String, LevelInfo> levels = DataProvider.GetLevels(args.CubeName, args.DimensionUniqueName, args.HierarchyUniqueName);
                foreach (LevelInfo li in levels.Values)
                {
                    Dictionary<String, LevelPropertyInfo> properties = DataProvider.GetLevelProperties(args.CubeName,
                        args.DimensionUniqueName,
                        args.HierarchyUniqueName,
                        li.UniqueName);
                    foreach (LevelPropertyInfo pi in properties.Values)
                    {
                        list.Add(pi);
                    }
                }
            }
            else
            {
                Dictionary<string, LevelPropertyInfo> properties = DataProvider.GetLevelProperties(args.CubeName,
                        args.DimensionUniqueName,
                        args.HierarchyUniqueName,
                        args.LevelUniqueName);
                foreach (LevelPropertyInfo pi in properties.Values)
                {
                    list.Add(pi);
                }
            }

            return XmlUtility.Obj2XmlStr(list, Common.Namespace);
        }

        String GetMeasures(MetadataQuery args)
        {
            Dictionary<String, MeasureInfo> list = DataProvider.GetMeasures(args.CubeName);
            return XmlUtility.Obj2XmlStr(list.Values.ToList(), Common.Namespace);
        }

        String GetMeasure(MetadataQuery args)
        {
            MeasureInfo list = DataProvider.GetMeasure(args.CubeName, args.MeasureUniqueName);
            return XmlUtility.Obj2XmlStr(list, Common.Namespace);
        }

        String GetKPIs(MetadataQuery args)
        {
            Dictionary<String, KpiInfo> list = DataProvider.GetKPIs(args.CubeName);
            return XmlUtility.Obj2XmlStr(list.Values.ToList(), Common.Namespace);
        }

        String GetKPI(MetadataQuery args)
        {
            KpiInfo kpi = DataProvider.GetKPI(args.CubeName, args.KPIName);
            return XmlUtility.Obj2XmlStr(kpi, Common.Namespace);
        }

        String GetLevel(MetadataQuery args)
        {
            LevelInfo list = DataProvider.GetLevel(args.CubeName, args.DimensionUniqueName, args.HierarchyUniqueName, args.LevelUniqueName);
            return XmlUtility.Obj2XmlStr(list, Common.Namespace);
        }

        String GetLevels(MetadataQuery args)
        {
            Dictionary<String, LevelInfo> list = DataProvider.GetLevels(args.CubeName, args.DimensionUniqueName, args.HierarchyUniqueName);
            return XmlUtility.Obj2XmlStr(list.Values.ToList(), Common.Namespace);
        }

        String GetDimensions(MetadataQuery args)
        {
            Dictionary<String, DimensionInfo> list = DataProvider.GetDimensions(args.CubeName);
            return XmlUtility.Obj2XmlStr(list.Values.ToList(), Common.Namespace);
        }

        String GetHierarchies(MetadataQuery args)
        {
            Dictionary<String, HierarchyInfo> list = DataProvider.GetHierarchies(args.CubeName, args.DimensionUniqueName);
            return XmlUtility.Obj2XmlStr(list.Values.ToList(), Common.Namespace);
        }

        String GetDimension(MetadataQuery args)
        {
            Dictionary<String, DimensionInfo> list = DataProvider.GetDimensions(args.CubeName);
            foreach (DimensionInfo info in list.Values)
            {
                if (info.UniqueName == args.DimensionUniqueName)
                {
                    return XmlUtility.Obj2XmlStr(info, Common.Namespace);
                }
            }
            return String.Empty;
        }

        String GetHierarchy(MetadataQuery args)
        {
            InvokeResultSchema res = new InvokeResultSchema(base.Id);

            Dictionary<String, HierarchyInfo> list = DataProvider.GetHierarchies(args.CubeName, args.DimensionUniqueName);
            foreach (HierarchyInfo info in list.Values)
            {
                if (info.UniqueName == args.HierarchyUniqueName)
                {
                    return XmlUtility.Obj2XmlStr(info, Common.Namespace);
                }
            }
            return String.Empty;
        }
    }
}
